package com.deep.seata.business.service.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.deep.seata.account.service.AccountService;
import com.deep.seata.business.service.BusinessService;
import com.deep.seata.common.model.account.Account;
import com.deep.seata.common.model.order.Order;
import com.deep.seata.common.model.storage.Storage;
import com.deep.seata.common.utils.CommonUtils;
import com.deep.seata.common.utils.DateUtils;
import com.deep.seata.product.service.OrderService;
import com.deep.seata.storage.service.StorageService;

import io.seata.core.context.RootContext;
import io.seata.spring.annotation.GlobalTransactional;

/**
 * 业务service实现
 *
 * @author deeprado
 * @time 2019年6月12日
 */
@RestController
public class BusinessServiceImpl implements BusinessService {
    private static final Logger LOGGER = LoggerFactory.getLogger(BusinessService.class);

    @Autowired
    private AccountService accountService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private StorageService storageService;

    /**
     * 付款
     *
     * @param accountId
     * @param orderId
     * @param storageId
     * @return
     * @author deeprado
     * @time 2019年6月12日
     */
    @GlobalTransactional
    @Override
    public Map<String, Object> purchase(@RequestParam("accountId") String accountId,
                                        @RequestParam("orderId") String orderId,
                                        @RequestParam("storageId") String storageId,
                                        @RequestParam(name = "debug", defaultValue = "") String debug) {
        try {
            LOGGER.info("accountId: {}", accountId);
            LOGGER.info("orderId {}", orderId);
            LOGGER.info("storageId {}", storageId);
            LOGGER.info("debug {}", debug);

            // 库存
            Storage storage = new Storage();
            storage.setStorageId(CommonUtils.genUUID());
            storage.setStorageName("name");
            if (debug.equals("storage")) {
                storage.setStorageCount(10);
            } else {
                storage.setStorageCount(20);
            }
            storage.setRemark("备注");
            storage.setLogicDel("N");
            LOGGER.info("storage {}", storage);

            // 订单
            Order order = new Order();
            order.setOrderId(CommonUtils.genUUID());
            order.setOrderNo("NO" + System.currentTimeMillis());
            order.setOrderDetail("详情");
            order.setCreateTime(DateUtils.formateTime(new Date()));
            order.setRemark("备注");
            order.setLogicDel("N");
            LOGGER.info("order {}", order);

            // 账号
            Account account = new Account();
            account.setAccountId(CommonUtils.genUUID());
            account.setAccountName("name");
            // 正常的
//            account.setAmount(new BigDecimal("100.5"));
            // 错误的，account服务会判断数量
//			account.setAmount(new BigDecimal("10"));
            if (debug.equals("account")) {
                account.setAmount(new BigDecimal("10"));
            } else {
                account.setAmount(new BigDecimal("100.5"));
            }
            account.setLogicDel("N");
            account.setRemark("备注");
            LOGGER.info("account {}", account);

            LOGGER.info("xid {}", RootContext.getXID());

            Map<String, Object> insert = storageService.insert(storage);
            if ((int) insert.get("status") != 200) {
                throw new RuntimeException((String) insert.get("message"));
            }

            Map<String, Object> insert2 = orderService.insert(order);
            if ((int) insert2.get("status") != 200) {
                throw new RuntimeException((String) insert2.get("message"));
            }
            Map<String, Object> insert3 = accountService.insert(account);
            if ((int) insert3.get("status") != 200) {
                throw new RuntimeException((String) insert3.get("message"));
            }

            Map<String, Object> result = new HashMap<>(16);
            result.put("status", 200);
            result.put("message", "付款成功！");
            return result;
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            throw new RuntimeException(e);
        }
    }

}
